package com.guazai.project.controller;

import cn.hutool.core.io.FileUtil;
import com.guazai.project.common.BaseResponse;
import com.guazai.project.common.ErrorCode;
import com.guazai.project.common.ResultUtils;
import com.guazai.project.exception.BusinessException;
import com.guazai.project.model.dto.file.UploadFileRequest;
import com.guazai.project.service.FileService;
import com.guazai.project.utils.AbsolutePathUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;

/**
 * @author qiteng
 */
@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {

    @Value("${guazai-api.upload.avatarLocalPath}")
    String avatarLocalPath;

    @Resource
    FileService fileService;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/uploadAvatar")
    public BaseResponse<String> uploadAvatar(@RequestPart("file") MultipartFile file) {
        log.info("前端上传文件到服务器");
        if (file == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件为空");
        }
        //文件重命名
        String ext = FilenameUtils.getExtension(file.getOriginalFilename());
        UUID uuid = UUID.randomUUID();
        String fileName = uuid + "." + ext;
        //获取绝对路径
        ApplicationHome applicationHome = new ApplicationHome(this.getClass());
        String path = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() + File.separator + avatarLocalPath + fileName;
        //文件上传到本地服务器
        try {
            file.transferTo(new File(path));
            return ResultUtils.success(fileName);
        } catch (IOException e) {
            log.info("文件上传失败");
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "头像上传失败");
        }
    }

    /**
     * 文件下载
     *
     * @param name
     */
    @GetMapping("/downloadAvatar")
    public void downloadAvatar(@RequestParam String name, HttpServletResponse response) throws IOException {
        if (StringUtils.isBlank(name)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件名参数为空");
        }
        log.info("开始向前端传输文件，文件名：{}", name);
        //找到文件
        //根据avatarLocalPath获得绝对路径
        String absolutePath = AbsolutePathUtils.getAbsolutePath(avatarLocalPath);
        //绝对路径拼上name
        String filePath = absolutePath + File.separator + name;
        //获取输入流
        FileInputStream fileInputStream = new FileInputStream(filePath);
        //从response获取输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //输出文件
        response.setContentType("image/jpeg");
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fileInputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
            outputStream.flush();
        }

        //关闭输入流和输出流
        fileInputStream.close();
        outputStream.close();
    }

    /**
     * 文件上传（阿里云 COS）
     *
     * @param file
     * @param uploadFileRequest
     * @param request
     * @return
     */
    @PostMapping("/uploadToAliOss")
    public BaseResponse<String> uploadToAliOss(@RequestPart("file") MultipartFile file,
                                               UploadFileRequest uploadFileRequest, HttpServletRequest request) throws IOException {
        log.info("前端上传文件到OSS");
        if (file == null || uploadFileRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件为空");
        }

        // 文件大小控制
        final long ONE_M = 1024 * 1024L;
        if (file.getSize() > ONE_M) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小不能超过 1M");
        }
        // 文件后缀限制
        String fileSuffix = FileUtil.getSuffix(file.getOriginalFilename());
        if (!Arrays.asList("jpeg", "jpg", "svg", "png", "webp").contains(fileSuffix)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件类型错误");
        }


        String fileName = fileService.uploadToAliOss(file);
        return ResultUtils.success(fileName);
    }
}
